home *** CD-ROM | disk | FTP | other *** search
- #include "mapping.h"
-
- /* [ x y ] [ a b ] = [ newX newY ]
- * [ c d ]
- */
- void MapXY(const mapping* map, Fixed* x, Fixed* y)
- {
- const Fixed* mx = &map->map[0][0];
- const Fixed* my = &map->map[1][0];
- const Fixed* mt = &map->map[2][0];
- Fixed tmpX = *x;
- Fixed tmpY = *y;
-
- *x = FixMul(*mx++, tmpX) + FixMul(*my++, tmpY) + *mt++;
- *y = FixMul(*mx, tmpX) + FixMul(*my, tmpY) + *mt++;
- }
-
- static Fixed ComputeDeterminant(const mapping* map)
- {
- return FixMul(map->map[0][0], map->map[1][1]) - FixMul(map->map[0][1], map->map[1][0]);
- }
-
- mapping* InvertMapping(mapping* map)
- {
- mapping inverse;
- Fixed det = ComputeDeterminant(map);
-
- if (det == 0)
- Debugger();
- inverse.map[0][0] = FixDiv(map->map[1][1], det);
- inverse.map[0][1] = - FixDiv(map->map[0][1], det);
- inverse.map[1][0] = - FixDiv(map->map[1][0], det);
- inverse.map[1][1] = FixDiv(map->map[0][0], det);
- inverse.map[2][0] = - FixMul(map->map[2][0], inverse.map[0][0]) - FixMul(map->map[2][1], inverse.map[1][0]);
- inverse.map[2][1] = - FixMul(map->map[2][0], inverse.map[0][1]) - FixMul(map->map[2][1], inverse.map[1][1]);
- *map = inverse;
-
- return map;
- }
-
- mapping* SetIdentityMapping(mapping* map)
- {
- Fixed* m = &map->map[0][0];
-
- *m++ = ff(1); *m++ = 0;
- *m++ = 0; *m++ = ff(1);
- *m++ = 0; *m++ = 0;
-
- return map;
- }
-
- mapping* ScaleMapping(mapping* map, Fixed scaleX, Fixed scaleY, Fixed aboutX, Fixed aboutY)
- {
- mapping scaleMap;
-
- SetIdentityMapping(&scaleMap);
- scaleMap.map[0][0] = scaleX;
- scaleMap.map[1][1] = scaleY;
- scaleMap.map[2][0] = aboutX - FixMul(scaleX, aboutX);
- scaleMap.map[2][1] = aboutY - FixMul(scaleY, aboutY);
-
- return ConcateMapping(map, &scaleMap);
- }
-
- Boolean IdentityMapping(const mapping* map)
- {
- return map->map[0][0] == ff(1) && map->map[1][1] == ff(1) &&
- !map->map[0][1] && !map->map[1][0] && !map->map[2][0] && !map->map[2][1];
- }
-
- mapping* ConcateMapping(mapping* dst, const mapping* map)
- {
- mapping concat;
-
- concat.map[0][0] = FixMul(dst->map[0][0], map->map[0][0]) + FixMul(dst->map[0][1], map->map[1][0]);
- concat.map[0][1] = FixMul(dst->map[0][0], map->map[0][1]) + FixMul(dst->map[0][1], map->map[1][1]);
- concat.map[1][0] = FixMul(dst->map[1][0], map->map[0][0]) + FixMul(dst->map[1][1], map->map[1][0]);
- concat.map[1][1] = FixMul(dst->map[1][0], map->map[0][1]) + FixMul(dst->map[1][1], map->map[1][1]);
- concat.map[2][0] = FixMul(dst->map[2][0], map->map[0][0]) + FixMul(dst->map[2][1], map->map[1][0]) + map->map[2][0];
- concat.map[2][1] = FixMul(dst->map[2][0], map->map[0][1]) + FixMul(dst->map[2][1], map->map[1][1]) + map->map[2][1];
-
- *dst = concat;
- return dst;
- }
-
- #define piOver180Frac 18740330L
-
- mapping* RotateMapping(mapping* map, Fixed angle, Fixed aboutX, Fixed aboutY)
- {
- mapping rotateMap;
- Fixed radians = FracMul(angle, piOver180Frac);
-
- rotateMap.map[0][0] = Frac2Fix(FracCos(radians));
- rotateMap.map[0][1] = - Frac2Fix(FracSin(radians));
- rotateMap.map[1][0] = - rotateMap.map[0][1];
- rotateMap.map[1][1] = rotateMap.map[0][0];
- rotateMap.map[2][0] = aboutX - FixMul(rotateMap.map[0][0], aboutX) - FixMul(rotateMap.map[1][0], aboutY);
- rotateMap.map[2][1] = aboutY - FixMul(rotateMap.map[0][1], aboutX) - FixMul(rotateMap.map[1][1], aboutY);
-
- if (IdentityMapping(map))
- *map = rotateMap;
- else
- ConcateMapping(map, &rotateMap);
- return map;
- }
-
- mapping* OffsetMapping(mapping* map, Fixed offsetX, Fixed offsetY)
- {
- map->map[2][0] += offsetX;
- map->map[2][1] += offsetY;
-
- return map;
- }
-
- Point* MapQDPoint(const mapping* map, Point* p)
- {
- Fixed x, y;
-
- x = ff(p->h);
- y = ff(p->v);
- MapXY(map, &x, &y);
- p->h = FixRound(x);
- p->v = FixRound(y);
-
- return p;
- }
-
- static void FlipRect(Rect* r)
- {
- if (r->top > r->bottom)
- { short tmp = r->top;
- r->top = r->bottom;
- r->bottom = tmp;
- }
- if (r->left > r->right)
- { short tmp = r->left;
- r->left = r->right;
- r->right = tmp;
- }
- }
-
- static void ExtendRect(Rect* r, Point p)
- {
- if (p.h < r->left)
- r->left = p.h;
- else if (p.h > r->right)
- r->right = p.h;
-
- if (p.v < r->top)
- r->top = p.v;
- else if (p.v > r->bottom)
- r->bottom = p.v;
- }
-
- Rect* MapRectangle(const mapping* map, Rect* r)
- {
- Rect bounds;
- Point p;
-
- SetPt(&p, r->left, r->top); MapQDPoint(map, &p); SetRect(&bounds, p.h, p.v, p.h, p.v);
- SetPt(&p, r->right, r->top); MapQDPoint(map, &p); ExtendRect(&bounds, p);
- SetPt(&p, r->right, r->bottom); MapQDPoint(map, &p); ExtendRect(&bounds, p);
- SetPt(&p, r->left, r->bottom); MapQDPoint(map, &p); ExtendRect(&bounds, p);
- *r = bounds;
-
- return r;
- }
-
- RgnHandle MapRectToRgn(const mapping* map, const Rect* r, RgnHandle rgn)
- {
- Point p, start;
-
- OpenRgn();
- SetPt(&p, r->left, r->top); MapQDPoint(map, &p); MoveTo(p.h, p.v); start = p;
- SetPt(&p, r->right, r->top); MapQDPoint(map, &p); LineTo(p.h, p.v);
- SetPt(&p, r->right, r->bottom); MapQDPoint(map, &p); LineTo(p.h, p.v);
- SetPt(&p, r->left, r->bottom); MapQDPoint(map, &p); LineTo(p.h, p.v);
- LineTo(start.h, start.v);
- CloseRgn(rgn);
-
- return rgn;
- }
-
-